<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    //面试看这个   https://mp.weixin.qq.com/s/aembi7YFc1MciJO1yQdlxg
    //ECMAScript 6.0（以下简称 ES6）是 JavaScript 语言的下一代标准，已经在 2015 年 6 月正式发布了。
    //它的目标，是使得 JavaScript 语言可以用来编写复杂的大型应用程序，成为企业级开发语言。
    //var 存在声明提前
//let ES6 新增了let命令，用来声明变量。它的用法类似于var，但是所声明的变量，只在let命令所在的代码块内有效。
    //例子1:
       console.log(i)
       for (var i = 0; i < 5; i++) {
           
       }
       console.log(i)
       //console.log(j)
       //另外，for循环还有一个特别之处，就是设置循环变量的那部分是一个父作用域，而循环体内部是一个单独的子作用域。
       for (let j = 0; j < 5; j++) {
           let j = "abc";
           console.log(j)
       }
       //console.log(j)
    //不存在声明提前 只要块级作用域内存在let命令，它所声明的变量就“绑定”（binding）这个区域，不再受外部的影响。（暂时性死区）
    if (true) {
        //console.log(name);
        let name = "你好呀"
    }
    function bar(x = y, y = 2) {
        return [x, y];
    }
    //bar(); // 报错
    // 不允许重复声明
    function func() {
        let a = 10;
        //let a = 1;
    }
    //ES6 的块级作用域 let实际上为 JavaScript 新增了块级作用域。
    function f1() {
        let n = 5;
        if (true) {
            let n = 10;
        }
        console.log(n); // 5
    }
    //上面的函数有两个代码块，都声明了变量n，运行后输出 5。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量n，最后输出的值才是 10。
    {
        let a = 1;
        console.log(a)
    }
    //console.log(a)
//const 语法
    //const声明的变量不得改变值，这意味着，const一旦声明变量，就必须立即初始化，不能留到以后赋值。
    const userName = "他好"
    //userName = "我好"
    const carr = [1,23,4];
    carr = {
        name:'好'
    }
    //const的作用域与let命令相同：只在声明所在的块级作用域内有效。
    //本质
    //const实际上保证的，并不是变量的值不得改动，而是变量指向的那个内存地址所保存的数据不得改动。
    //1:对于简单类型的数据（数值、字符串、布尔值），值就保存在变量指向的那个内存地址，因此等同于常量。
    //2:但对于复合类型的数据（主要是对象和数组），变量指向的内存地址，保存的只是一个指向实际数据的指针，const只能保证这个指针是固定的（即总是指向另一个固定的地址）
    //3:至于它指向的数据结构是不是可变的，就完全不能控制了。因此，将一个对象声明为常量必须非常小心。
    
</script>
</body>
</html>